/*
   \file  image_utils.cc
   \brief Image processing utility routines.

   This file defines some non-template functions utilized by the generic
   image processing routines defined in image_utils.hh.
*/

/*
   This file is part of libgist.

   libgist is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by the
   Free Software Foundation; either version 2 of the License, or (at your
   option) any later version.

   libgist is distributed in the hope that it will be useful, but WITHOUT
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
   for more details.

   You should have received a copy of the GNU General Public License
   along with libgist; if not, write to the Free Software Foundation,
   Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/

/*
   REVISION HISTORY

   $HeadURL: http://libgist.googlecode.com/svn/trunk/src/image_utils.cc $
   $Id: image_utils.cc 42 2011-08-22 10:51:07Z libgist@gmail.com $
*/

//------------------------------ HEADERS --------------------------------

// Standard C++
#include <numeric>
#include <algorithm>
#include <functional>
#include <vector>

// Standard C
#include <math.h>

//----------------------- NAMESPACE DEFINITION --------------------------

namespace gist {

//---------------------------- CONVOLUTION ------------------------------

std::vector<float> gaussian_kernel(float sigma, int half_width)
{
   std::vector<float> kernel(2 * half_width + 1) ;

   // Start off with a value of one at the center of the kernel
   kernel[half_width] = 1 ;

   // Build the bell curved shape moving away from center
   const float _1_OVER_2_SIGMA_SQR = 1/(2 * sigma * sigma) ;
   for (int i = 1; i <= half_width; ++i)
      kernel[half_width + i] =
      kernel[half_width - i] = expf(i * i * _1_OVER_2_SIGMA_SQR) ;

   // Normalize the kernel
   float sum = std::accumulate(kernel.begin(), kernel.end(), 0.0f) ;
   std::transform(kernel.begin(), kernel.end(), kernel.begin(),
                  std::bind2nd(std::multiplies<float>(), 1/sum)) ;

   return kernel ;
}

//-----------------------------------------------------------------------

} // end of namespace encapsulating this file's definitions

/* So things look consistent in everyone's emacs... */
/* Local Variables: */
/* indent-tabs-mode: nil */
/* End: */

